package com.markbuikema.juliana32.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.util.Log;

import com.markbuikema.juliana32.enums.Category;
import com.markbuikema.juliana32.enums.CompType;
import com.markbuikema.juliana32.model.nieuws.NieuwsItem;
import com.markbuikema.juliana32.model.teams.GameEvent;
import com.markbuikema.juliana32.model.teams.Table;
import com.markbuikema.juliana32.model.teams.Team;
import com.markbuikema.juliana32.util.KnvbDataManager.KnvbCallback;

public class DataManager {

	private static DataManager instance;
	private List<NieuwsItem> nieuwsItems;
	private List<Team> teams;

	private DataManager() {
	}

	public static DataManager getInstance() {
		if (instance == null)
			instance = new DataManager();
		return instance;
	}

	public List<NieuwsItem> getNieuwsItems() {
		if (nieuwsItems == null) {
			nieuwsItems = new ArrayList<NieuwsItem>();
		}

		return nieuwsItems;
	}

	public void setNieuwsItems(List<NieuwsItem> nieuwsItems) {
		this.nieuwsItems = nieuwsItems;
	}

	public List<Team> getTeams() {
		if (teams == null) {
			teams = new ArrayList<Team>();
		}

		return teams;
	}

	public void setTeams(List<Team> teams) {
		this.teams = teams;
	}

	public void printLoadingStatus() {
		// Log.d("DataManager", "Teams loaded: " + (teams != null));
		// Log.d("DataManager", "Nieuws loaded: " + (nieuwsItems != null));
	}

	public NieuwsItem getNieuwsItemById(String itemRequestId) {
		NieuwsItem item = null;
		for (NieuwsItem i : DataManager.getInstance().getNieuwsItems())
			if (i.getId().equals(itemRequestId))
				return i;
		return null;
	}

	public List<Team> getTeamsFromCategory(Category cat) {
		if (cat == null)
			return teams;

		List<Team> teams = new ArrayList<Team>();
		for (Team team : teams)
			if (team.getCategory() == cat)
				teams.add(team);

		return teams;
	}

	public Team findTeamById(String teamId) {
		for (Team team : teams)
			if (team.getId().equals(teamId))
				return team;
		return null;
	}

	public void loadTeams(final DataLoadedCallback callback) {

		KnvbDataManager knvb = KnvbDataManager.getInstance();

		knvb.request("/teams", null, new KnvbCallback() {

			@Override
			public void onDataReceived(String json) {

				final List<Team> teams = KnvbParser.parseTeams(json);
				setTeams(teams);

				new AsyncTask<Void, Object, Void>() {

					@Override
					protected Void doInBackground(Void... params) {
						HttpParams faster = new BasicHttpParams();
						faster.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
						
						HttpClient client = new DefaultHttpClient(faster);
						HttpGet get = new HttpGet(Constants.TEAM_PHOTOS_URL);
						try {
							HttpResponse response = client.execute(get);
							String output = EntityUtils.toString(response.getEntity());
							JSONArray list = new JSONArray(output);

							for (int i = 0; i < list.length(); i++) {
								JSONObject object = list.getJSONObject(i);

								String teamId = object.getString("teamId");
								String teamPhoto = object.getString("teamPhoto");

								for (Team team : getTeams()) {
									if (teamId.equals(team.getId())) {
										publishProgress(team, teamPhoto);
										break;
									}
								}
							}

						} catch (ClientProtocolException e) {
							e.printStackTrace();
						} catch (IOException e) {
							e.printStackTrace();
						} catch (JSONException e) {
							e.printStackTrace();
						}
						return null;
					}

					public void onProgressUpdate(Object... values) {

						Team team = (Team) values[0];
						String photo = (String) values[1];

						team.setTeamPhoto(photo);


					}

				}.execute();

				KnvbDataManager.getInstance().request("/competities", null, new KnvbCallback() {

					@Override
					public void onDataReceived(String json) {
						KnvbParser.parseAndAddLeagues(json);

						for (final Team team : teams) {
							KnvbCallback tableCallback = new KnvbCallback() {

								@Override
								public void onDataReceived(String json) {
									List<Table> tables = KnvbParser.parseTables(json);

									team.addTables(tables);
								}
							};

							for (int type = 0; type < CompType.values().length; type++) {

								CompType compType = CompType.values()[type];

								HashMap<String, String> tableArgs = new HashMap<String, String>();

								tableArgs.put("periode", "A");
								tableArgs.put("pouleid", "all");
								tableArgs.put("comptype", compType.toString());
								KnvbDataManager.getInstance().request("/teams/" + team.getId() + "/ranking", tableArgs, tableCallback);

								final int finalType = type;

								KnvbCallback pastGamesCallback = new KnvbCallback() {

									@Override
									public void onDataReceived(String json) {
										List<GameEvent> games = KnvbParser.parseGames(json);
										team.addPastGames(CompType.values()[finalType], games);
									}
								};

								HashMap<String, String> pastGameArgs = new HashMap<String, String>();
								pastGameArgs.put("weeknummer", "A");
								pastGameArgs.put("comptype", compType.toString());
								KnvbDataManager.getInstance().request("/teams/" + team.getId() + "/results", pastGameArgs, pastGamesCallback);

								KnvbCallback upcomingGamesCallback = new KnvbCallback() {

									@Override
									public void onDataReceived(String json) {
										List<GameEvent> games = KnvbParser.parseGames(json);
										team.addUpcomingGames(CompType.values()[finalType], games);
									}
								};

								HashMap<String, String> upcomingGameArgs = new HashMap<String, String>();
								upcomingGameArgs.put("weeknummer", "A");
								upcomingGameArgs.put("comptype", compType.toString());
								KnvbDataManager.getInstance().request("/teams/" + team.getId() + "/schedule", upcomingGameArgs, upcomingGamesCallback);

							}

						}
					}
				});

				callback.onDataLoaded(teams);

			}
		});

	}

	public interface DataLoadedCallback {
		public void onDataLoaded(List<?> data);
	}

}